# 标题：变量江湖：Python作用域的三重境界

#[钛妹]: 钛哥！我网购的快递总送错地方！
#[钛妹]: 就像代码里的变量到处乱跑...
#[钛妹]: 有没有控制变量活动范围的方法呀？

#[钛哥]: 问对人啦！这就是作用域的学问！
#[钛哥]: 变量就像快递包裹，配送范围很重要！
#[钛哥]: 咱们从最简单的局部作用域开始——

#[钛妹]: 快看这个函数里的变量！
def delivery_1():
    package = "生鲜水果"
    print(package)  # 能正常打印

delivery_1()

#[钛哥]: 注意！package变量是局部变量
#[钛哥]: 只能在delivery_1内部使用
#[钛妹]: 那外部访问会怎样？
# print(package)  # 报错NameError

#[钛妹]: 明白了！函数就像快递站，包裹不出站！

#[钛妹]: 如果快递站里还有分拣中心呢？
def delivery_2():
    package = "电子产品"
    
    def sorting_room():
        print("分拣:", package)  # 能访问外部函数变量
    
    sorting_room()

delivery_2()  # 输出"分拣: 电子产品"

#[钛哥]: 嵌套函数可以访问外层函数的变量
#[钛哥]: 这叫Enclosing作用域，像套娃快递箱
#[钛妹]: 哇！包裹在分拣中心也能正常流通！

#[钛妹]: 有没有全国通用的快递包裹？
global_package = "紧急物资"

def delivery_3():
    print("全局运输:", global_package)

delivery_3()  # 正常访问
print("直接访问:", global_package)  # 也能访问

#[钛哥]: 全局变量就像顺丰全国仓
#[钛哥]: 任何地方都能访问到
#[钛妹]: 原来全局变量是VIP包裹！

#[钛妹]: 如果站内站外同名包裹咋办？
warehouse = "普通快递"

def delivery_4():
    warehouse = "加急快递"
    print("站内优先:", warehouse)  # 输出加急快递

delivery_4()
print("站外查看:", warehouse)  # 还是普通快递

#[钛哥]: 局部变量会覆盖全局同名变量
#[钛哥]: 就像分站包裹优先用本地库存
#[钛妹]: 原来Python变量也懂"就近原则"！

#[钛妹]: 怎么修改全局库存呢？
total = 100

def update_global():
    global total
    total += 50
    print("修改后全局:", total)

update_global()  # 输出150
print("验证全局:", total)  # 也变成150

#[钛哥]: global声明后就能修改全局变量
#[钛哥]: 像拿到了总部修改权限
#[钛妹]: 原来global是管理员的钥匙！

#[钛妹]: 那嵌套函数怎么改外层变量？
def outer_warehouse():
    stock = 200
    
    def inner_update():
        nonlocal stock
        stock -= 50
    
    inner_update()
    print("外层库存:", stock)  # 输出150

outer_warehouse()

#[钛哥]: nonlocal用于修改嵌套作用域的变量
#[钛哥]: 比global更精准的层级控制
#[钛妹]: 就像区域经理调整分仓库存！

#[钛妹]: 这种特性有什么用武之地呢？
def create_counter():
    count = 0
    
    def counter():
        nonlocal count
        count += 1
        return count
    
    return counter

counter1 = create_counter()
print(counter1())  # 1
print(counter1())  # 2

#[钛哥]: 闭包通过nonlocal保留状态
#[钛哥]: 实现有记忆的功能函数
#[钛妹]: 原来计数器是这么实现的！

#[钛妹]: 听说装饰器也用作用域？
def logger(func):
    def wrapper(*args):
        print(f"正在执行: {func.__name__}")
        return func(*args)
    return wrapper

@logger
def send_package():
    print("包裹已发出！")

send_package()  # 先打印日志再发包裹

#[钛哥]: 装饰器利用嵌套作用域保存原函数
#[钛哥]: 功能增强却不修改原函数
#[钛妹]: 作用域简直是Python的魔法结界！

#[钛妹]: 这么多作用域优先级怎么算？
global_var = "全局"

def outer():
    enclosing_var = "外层"
    
    def inner():
        local_var = "内层"
        print(local_var)        # 内层
        print(enclosing_var)    # 外层
        print(global_var)       # 全局
    
    inner()

outer()

#[钛哥]: 查找顺序：局部->外层->全局->内置
#[钛哥]: 就像快递优先本地，再逐级扩大范围
#[钛妹]: 原来Python找变量像快递路线规划！

#[钛妹]: 今天学了三把金钥匙：
#[钛妹]: 1. 局部变量只在函数内有效
#[钛妹]: 2. global修改全局，nonlocal改外层
#[钛妹]: 3. 作用域链决定变量查找顺序

#[钛哥]: 记牢这些，变量再也不会"迷路"啦！
#[钛妹]: 对了各位！持续学习才是硬道理！
#[钛妹]: 点赞关注不迷路！